home *** CD-ROM | disk | FTP | other *** search
- /*
- * coil.c - Create a coil of n turns between two points in space
- *
- * Alexander Enzmann
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #ifdef MAC
- #include <console.h>
- #endif
- #include "def.h"
- #include "lib.h"
-
- static void
- determine_coil_point(COORD4 *pos, COORD4 *norm,
- double theta, double phi, double r0, double r1, double d0)
- {
- COORD4 v0, v1, vd;
- double len;
-
- /* Center of the coil */
- SET_COORD4(v0, r0 * cos(theta), r0 * sin(theta), d0, 1.0);
-
- /* Point on the coil */
- SET_COORD4(*pos, (r0 + r1 * sin(phi)) * cos(theta),
- (r0 + r1 * sin(phi)) * sin(theta),
- (r1 * cos(phi)) + d0,
- 1.0);
-
- /* Direction from center to point */
- SUB3_COORD(vd, *pos, v0);
- len = lib_normalize_coord3(&vd);
-
- v0.x = r1*cos(phi)*cos(theta);
- v1.x = -(r0 + r1*sin(phi))*sin(theta);
-
- v0.y = r1*cos(phi)*sin(theta);
- v1.y = (r0 + r1*sin(phi))*cos(theta);
-
- v0.z = -r1*sin(phi);
- v1.z = 0.0;
-
- CROSS(*norm, v0, v1);
- len = lib_normalize_coord3(norm);
-
- len = DOT_PRODUCT(*norm, vd);
- if (len < 0.0) {
- norm->x *= -1.0;
- norm->y *= -1.0;
- norm->z *= -1.0;
- }
- norm->w = 0.0;
- }
-
- /* Wrap a coil around a sphere of radius sr, centered at d=t */
- static void
- generate_cyl_coil(COORD4 *start, COORD4 *end,
- int turns, int step_per_turn,
- double r0, double r1,
- double t, double sr,
- char *txname)
- {
- int i, j, k;
- COORD4 p, p0, p1, n0;
- COORD4 dir;
- MATRIX trans;
- double dist, u0, u1, d0, d1, len;
- double deltad, deltau;
- double t0, t1, tm;
- double rt, q, rdif = r0 - r1, sr2 = sr * sr;
-
- SUB3_COORD(dir, *end, *start);
- dist = lib_normalize_coord3(&dir);
-
- /* Coils are sorta complex, so make bounding slabs oriented along
- the direction of the coil */
- lib_output_bounding_slab(&dir);
-
- /* Figure out the transform to get from the parametrically defined
- coil to the start-end line */
- lib_create_canonical_matrix(trans, start, &dir);
-
- /* Figure out the lower and upper limits that the sphere will
- affect the coil */
- t0 = dist * t - sr;
- t1 = dist * t + sr;
- tm = (t1 + t0) / 2.0;
-
- /* Calculate the step sizes for making the coil */
- deltad = dist / (double)(turns * step_per_turn);
- deltau = 2.0 * PI / (double)step_per_turn;
-
- /* Start generating the cylinders making up the coil */
- for (i=0,d0=0.0;i<turns;i++) {
- for (j=0;j<step_per_turn;j++,d0+=deltad) {
- d1 = d0 + deltad;
- u0 = (double)j * deltau;
- u1 = u0 + deltau;
- if (d0 > t0 && d0 < t1) {
- q = fabs(d0 - tm);
- q = sqrt(sr2 - q * q);
- if (q > rdif)
- rt = r0 + (q - rdif);
- else
- rt = r0;
- }
- else
- rt = r0;
- /* fprintf(stderr, "d: %g, rt: %g\n", d0, rt); */
- determine_coil_point(&p, &n0, u0, 0.0, rt, 0.0, d0);
- lib_transform_coord(&p0, &p, trans);
- p0.w = r1;
- if (d1 > t0 && d1 < t1) {
- q = fabs(d1 - tm);
- q = sqrt(sr2 - q * q);
- if (q > rdif)
- rt = r0 + (q - rdif);
- else
- rt = r0;
- }
- else
- rt = r0;
- determine_coil_point(&p, &n0, u1, 0.0, rt, 0.0, d1);
- lib_transform_coord(&p1, &p, trans);
- p1.w = r1;
- lib_output_cylcone(&p0, &p1, txname);
- lib_output_sphere(&p0, txname);
- }
- }
- /* Cap the end */
- lib_output_sphere(&p1, txname);
- }
-
- void
- main(int argc, char *argv[])
- {
- COORD4 back_color, coil_color, dir;
- COORD4 center_pt, end_pt, light;
- COORD4 from, at, up;
- char *txname;
-
- MATRIX m1, m2;
-
- #ifdef MAC
- argc = ccommand(&argv);
- #endif
-
- /* output viewpoint */
- SET_COORD(from, 0.0, 7.0,-7.0);
- SET_COORD(at, 0.0, 1.0, 2.0);
- SET_COORD(up, 0.0, 1.0, 0.0);
- lib_output_viewpoint(&from, &at, &up, 30.0, 1.0, 1.0, 256, 256);
-
- /* output background color - dark blue */
- SET_COORD(back_color, 0.039, 0.18, 0.376);
- lib_output_background_color(&back_color);
-
- /* Output bounding slabs oriented along the coordinate axes */
- SET_COORD(dir, 1.0, 0.0, 0.0);
- lib_output_bounding_slab(&dir);
- SET_COORD(dir, 0.0, 1.0, 0.0);
- lib_output_bounding_slab(&dir);
- SET_COORD(dir, 0.0, 0.0, 1.0);
- lib_output_bounding_slab(&dir);
-
- /* output light source */
- SET_COORD(light,-10.0, 10.0,-20.0);
- lib_output_light(&light);
- SET_COORD(light, 10.0, 10.0,-20.0);
- lib_output_light(&light);
-
- /* output sphere color - blue */
- SET_COORD4(center_pt, 0.0, 1.0, 2.0, 1.5);
- SET_COORD(coil_color, 0.2, 0.2, 1.0);
- txname = lib_output_color(&coil_color, 0.1, 0.1, 0.4, 3.0, 0.0, 0.8, 1.3);
- lib_output_sphere(¢er_pt, txname);
-
- /* output coil color - red */
- SET_COORD(coil_color, 1.0, 0.2, 0.2);
- txname = lib_output_color(&coil_color, 0.2, 0.8, 0.4, 5.0, 0.0, 0.0, 0.0);
-
- /* compute and output coil */
- SET_COORD4(center_pt,-1.0,-1.0, 0.0, 1.0);
- SET_COORD4(end_pt, 1.0, 3.0, 4.0, 1.0);
- generate_cyl_coil(¢er_pt, &end_pt, 24, 72, 1.0, 0.05, 0.5, 1.5, txname);
- }
-